home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / smail-3.1.28 / util / mksort.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-05  |  3.4 KB  |  208 lines

  1. /* @(#)util/mksort.c    1.5 9/6/92 01:10:32 */
  2.  
  3. /*
  4.  *    Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
  5.  *    Copyright (C) 1992  Ronald S. Karr
  6.  * 
  7.  * See the file COPYING, distributed with smail, for restriction
  8.  * and warranty information.
  9.  */
  10.  
  11. /*
  12.  * mksort.c:
  13.  *    Take a list of lines and sort them.  If the flag -f is given,
  14.  *    then ignore case in comparisons.
  15.  */
  16. #include <stdio.h>
  17. #include <ctype.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #include "defs.h"
  21. #include "smail.h"
  22. #include "extern.h"
  23. #include "field.h"
  24. #include "addr.h"
  25. #include "dys.h"
  26. #include "exitcodes.h"
  27.  
  28. char *program;                /* argv[0] from main */
  29. int debug = 0;
  30. FILE *errfile = stderr;
  31.  
  32. static int cmp(), cmpic();
  33. static char **mkvectors();
  34. static int read_lines();
  35.  
  36. /*ARGSUSED*/
  37. void
  38. main(argc, argv)
  39.     int argc;
  40.     char **argv;
  41. {
  42.     struct str strings;
  43.     char **mkvectors();
  44.     int (*compare_fun)() = cmp;
  45.     int ct = 0;
  46.     char **v;
  47.     int i;
  48.  
  49.     program = *argv++;
  50.  
  51.     /* if -f, then perform case-folded comparisons */
  52.     if (*argv && EQ(*argv, "-f")) {
  53.     compare_fun = cmpic;
  54.     argv++;
  55.     }
  56.  
  57.     STR_INIT(&strings);
  58.     if (*argv == NULL) {
  59.     ct += read_lines(&strings, stdin);
  60.     }
  61.     while (*argv) {
  62.     FILE *f;
  63.  
  64.     if (EQ(*argv, "-")) {
  65.         f = stdin;
  66.     } else {
  67.         f = fopen(*argv, "r");
  68.         if (f == NULL) {
  69.         (void) fprintf(stderr, "%s: cannot open %s: ", program, *argv);
  70.         perror("");
  71.         exit(errno);
  72.         }
  73.     }
  74.     ct += read_lines(&strings, f);
  75.     argv++;
  76.     }
  77.  
  78.     v = mkvectors(ct, strings.p);
  79.     qsort((char *)v, ct, sizeof(char *), compare_fun);
  80.  
  81.     for (i = 0; i < ct; i++) {
  82.     printf("%s\n", v[i]);
  83.     }
  84.  
  85.     exit(0);
  86. }
  87.  
  88. static int
  89. read_lines(ssp, f)
  90.     register struct str *ssp;
  91.     register FILE *f;
  92. {
  93.     register int c;
  94.     int ct = 0;
  95.  
  96.     while ((c = getc(f)) != EOF) {
  97.     if (c == '\n') {
  98.         STR_NEXT(ssp, '\0');
  99.         ct++;
  100.     } else {
  101.         STR_NEXT(ssp, c);
  102.     }
  103.     }
  104.  
  105.     return ct;
  106. }
  107.  
  108. static char **
  109. mkvectors(ct, strings)
  110.     int ct;                /* count of strings */
  111.     char *strings;            /* null-terminated strings */
  112. {
  113.     char **v;
  114.     register char **vp;
  115.     register char *sp = strings;
  116.  
  117.     v = vp = (char **)xmalloc(ct * sizeof(char *));
  118.     for (sp = strings; ct; ct--, sp += strlen(sp) + 1) {
  119.     *vp++ = sp;
  120.     }
  121.     return v;
  122. }
  123.  
  124. static int
  125. cmp(a, b)
  126.     char **a;
  127.     char **b;
  128. {
  129.     char *s1 = *a;
  130.     char *s2 = *b;
  131.     register int c1, c2;
  132.  
  133.     for (;;) {
  134.     c1 = *s1++;
  135.     c2 = *s2++;
  136.     if (isspace(c1) || c1 == ':')
  137.         c1 = '\0';
  138.     if (isspace(c2) || c2 == ':')
  139.         c2 = '\0';
  140.     if (c1 != c2)
  141.         return c1 - c2;
  142.     if (c1 == '\0')
  143.         break;
  144.     }
  145.     return c1 - c2;
  146. }
  147.  
  148. static int
  149. cmpic(a, b)
  150.     char **a;
  151.     char **b;
  152. {
  153.     char *s1 = *a;
  154.     char *s2 = *b;
  155.     register int c1, c2;
  156.  
  157.     for (;;) {
  158.     c1 = lowercase(*s1++);
  159.     c2 = lowercase(*s2++);
  160.     if (isspace(c1) || c1 == ':')
  161.         c1 = '\0';
  162.     if (isspace(c2) || c2 == ':')
  163.         c2 = '\0';
  164.     if (c1 != c2)
  165.         return c1 - c2;
  166.     if (c1 == '\0')
  167.         break;
  168.     }
  169.     return c1 - c2;
  170. }
  171.  
  172. /*
  173.  * standalone versions of some referenced routines
  174.  */
  175. char *
  176. xmalloc(len)
  177.     int len;
  178. {
  179.     char *malloc();
  180.     register char *ret = malloc(len);
  181.  
  182.     if (ret == NULL) {
  183.     (void) fprintf(stderr, "%s: out of memory!\n", program);
  184.     }
  185.     return ret;
  186. }
  187.  
  188. char *
  189. xrealloc(s, len)
  190.     char *s;
  191.     int len;
  192. {
  193.     char *realloc();
  194.     register char *ret = realloc(s, len);
  195.  
  196.     if (ret == NULL) {
  197.     (void) fprintf(stderr, "%s: out of memory!\n", program);
  198.     }
  199.     return ret;
  200. }
  201.  
  202. void
  203. xfree(s)
  204.     char *s;
  205. {
  206.     free(s);
  207. }
  208.